package com.woniuxy.commons.interceptor;

import com.woniuxy.commons.annotation.RequirePerms;
import com.woniuxy.commons.exception.AccessDeniedException;
import com.woniuxy.commons.exception.NoLoginException;
import com.woniuxy.commons.request.Message;
import com.woniuxy.commons.service.FeignUserService;
import com.woniuxy.commons.util.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @author: Mr·Xiang
 * @create 2024-05-24 14:12
 */
@Slf4j
@Component
public class PermsInterceptor implements HandlerInterceptor {
    // @Lazy延迟注入，在创建对象时不注入，在需要用的时候注入
    @Lazy
    @Resource
    private FeignUserService feignUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("拦截请求");
        String token = request.getHeader("Authorization");
        if (token != null){
            request.getSession().setAttribute("uid", JWTUtil.getuid(token));
        }
        // 判断是否拦截的method
        if (handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 获取方法
            Method method = handlerMethod.getMethod();
            // 判断方法上是否有权限注解
            if (method.isAnnotationPresent(RequirePerms.class)){
                // 获取权限注解对象
                RequirePerms requirePerms = method.getAnnotation(RequirePerms.class);
                // 获取权限信息
                String perms = requirePerms.value();
                log.info("权限：{}", perms);
                // 通过用户信息找“用户”模块获取到当前用户的权限信息与方法上的权限进行对比
                if (token == null){
                    throw new NoLoginException(Message.PLEASE_LOGIN);
                }
                // 将token作为参数传给用户模块
                List<String> list = feignUserService.findPermsByToken(token).getData();
                if (!list.contains(perms)){
                    throw new AccessDeniedException(Message.ACCESS_DENIED);
                }
            }
        }
        return true;
    }
}
